home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d20
/
msgq160s.arc
/
MSGEDQ.C
< prev
next >
Wrap
Text File
|
1991-10-26
|
18KB
|
885 lines
/*
* MSGEDQ.C - Main program
*
* Msged/Q message editor for QuickBBS Copyright 1990 by P.J. Muller
*
*/
#include <process.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>
#if defined(__MSC__) || defined(__TURBOC__) || defined(__JPIC__)
#include <fcntl.h>
#endif
#define MAIN
#include "msged.h"
#include "screen.h"
#include "bmg.h"
#include "maincmds.h"
#include "qmsgbase.h"
#include "shell.h"
#if 0
#ifdef __ZTC__
unsigned _stack = 4096;
#endif
#endif
#if defined(__TURBOC__)
unsigned int _stklen = 4096; /* Turbo C min. stack size */
#endif
#ifdef __JPIC__
int _ISDST = 0; /* hack */
#endif
#define ENDFREQ 550 /* Hz */
#define ENDLEN 1 /* 1/18.2 s */
#define S_HEAD 1
#define S_TEXT 2
#define S_BOTH (S_TEXT|S_HEAD)
static void highest(void);
static int command; /* keyboard command */
static int direction = RIGHT;
static int root = 0; /* root message of a thread */
static int back = 0;
static int start(int argc, char *argv[]);
static void empty(void);
static void gotomsg(int i);
static void srch(int what); /* 1-header, 2-text, 3-both */
static void toarea(int n);
static void retry(void);
void go_last()
{
setcur(CurBoard, lastreadmsg(CurBoard));
root = curmsg(CurBoard);
}
void escquit()
{
if (confirm(confirmations))
cleanup();
}
void deletemsg()
{
if (!confirm(confirmations))
return;
msgdelete(curmsg(CurBoard),arealist[area].echomail,arealist[area].netmail);
if (direction == LEFT)
left(); /* for Peter */
}
void link_from()
{
if (!msgat(CurBoard,message.header.reply))
return;
back = curmsg(CurBoard);
setcur(CurBoard,message.header.reply);
}
void link_to()
{
if (!msgat(CurBoard,message.header.up))
return;
back = curmsg(CurBoard);
setcur(CurBoard,message.header.up);
}
void marklast()
{
setlastread(CurBoard,curmsg(CurBoard));
}
void view()
{
shownotes = !shownotes;
#ifdef SEENBY
if (shownotes)
seenbys = shownotes;
#endif
}
void go_root()
{
if (!msgat(CurBoard,root))
return;
back = curmsg(CurBoard);
setcur(CurBoard,root);
highest();
}
void rotate()
{
rot13 = (rot13 + 1) % 4;
}
void togaddr()
{
techie = !techie;
} /* togaddr */
void go_dos()
{
#ifndef MINI
os();
#endif
}
void main(int argc, char *argv[])
{
arealist = NULL;
msgbuf.first = NULL;
#if defined(__MSC__) || defined(__TURBOC__) || defined(__JPIC__)
_fmode = (unsigned int) O_BINARY; /* default open mode - binary */
#endif
command = start(argc,argv);
while (1) { /* endless loop... exit is through cleanup */
if (command & 0xff) {
if (isdigit(command))
gotomsg(command - 0x30);
else if (mainckeys[command])
mainckeys[command & 0xff]();
}
else if (mainakeys[command >> 8])
mainakeys[command >> 8]();
if (countmsg(CurBoard) < 1) {
empty();
command = getkey();
}
else {
int last = lastmsg(CurBoard);
if (!msgat(CurBoard,curmsg(CurBoard))) { /* e.g. after delete */
setcur(CurBoard,msgnext(CurBoard,curmsg(CurBoard)));
highest();
} /* if */
if (lastreadmsg(CurBoard) > last)
setlastread(CurBoard,last);
if (curmsg(CurBoard) > last)
setcur(CurBoard,last);
if (!readmsg(&message, curmsg(CurBoard))) {
retry();
command = direction;
continue;
}
command = showmsg(message);
} /* else */
} /* while */
} /* main */
static void retry(void)
{
int ch;
gotoxy(9,1);
clreol();
set_color(co_warn);
bputs("Error reading message, (R)etry or (A)bort? ");
video_update();
do {
ch = getkey() & 0x7f;
ch = tolower(ch); /* tolower might be a macro */
} while ((ch != 'r') && (ch != 'a'));
bputc((char) ch);
set_color(co_normal);
if (ch == 'a')
cleanup();
} /* retry */
void cleanup()
{
int echomail = 0, netmail = 0;
int result;
cls();
for (area = 0; area < areas; area++) {
if (arealist[area].echomail)
echomail |= arealist[area].new;
if (arealist[area].netmail)
netmail |= arealist[area].new;
} /* for */
if (!closemsgbase()) {
set_color(co_warn);
bputs("Error closing message base.");
set_color(co_normal);
gotoxy(1,2);
} /* if */
if (useusersbbs) /* update USERS.BBS */
updatehigh(usernum, highmsgread);
set_color(co_hilite);
if (echomail && netmail) {
bputs("New Echomail and Netmail entered.");
result = 3;
} else if (echomail) {
bputs("New Echomail entered.");
result = 2;
} else if (netmail) {
bputs("New Netmail entered.");
result = 1;
} else {
bputs("No new net- or echomail entered.");
result = 0;
} /* else */
set_color(co_normal);
gotoxy(1,3);
bprintf("* Exiting from Msged/Q with errorlevel %d.", result);
gotoxy(1,4);
video_update();
video_end();
exit(result);
} /* cleanup */
void halt(int status)
{
if (status != 0)
fprintf(stderr,"\nExiting with errorlevel %d\n",status);
exit(status);
} /* halt */
void fatal(char *s)
{
fprintf(stderr, "\n%s\n", s);
fprintf(stderr, "Press <Return> to exit.\n");
while (getchar() != '\n') /* nothing */;
cleanup();
} /* fatal */
void outamemory()
{
fatal("I've run out of memory!");
} /* outamemory */
static void empty()
{
cls();
gotoxy(3, maxy / 2);
set_color(co_hilite);
bprintf("No messages in '%s'!", arealist[area].description);
set_color(co_normal);
} /* empty */
static void search()
{
srch(S_BOTH);
} /* srchall */
static void srchhdr()
{
srch(S_HEAD);
} /* srchhdr */
static void srch(int what)
{
static bmgARG pattern;
static char prompt[bmgMAXPAT];
static char patstr[bmgMAXPAT];
static int lastfound = 0;
MSGHEADER hdr;
int tmp2;
char *s;
int tmp;
int curarea = area;
gotoxy(9,1);
clreol();
set_color(co_info);
bputs("Find: ");
set_color(co_normal);
if (bgets(prompt,sizeof(prompt)) == ABORT)
return;
if (strcmpl(prompt,patstr) != 0) { /* changed, so recompile */
memset(patstr,0,sizeof(patstr));
memset(&pattern,0,sizeof(bmgARG));
strncpy(patstr,prompt,sizeof(prompt));
bmgCompile(patstr,&pattern,TRUE);
lastfound = 0;
} /* if */
gotoxy(9,1);
clreol();
set_color(co_info);
for (;;) {
do {
s = NULL;
tmp = curmsg(CurBoard);
if (readheader(tmp, &hdr)) {
if (what & S_TEXT)
s = readtext(&hdr);
if (what & S_HEAD) {
if (s == NULL) {
if ((s = malloc(36+36+73+1)) != NULL)
*s = EOS;
} else {
s = realloc(s,strlen(s)+1 + 36+36+73+1);
} /* else */
if (s != NULL) {
strcat(s, hdr.to);
strcat(s, hdr.from);
strcat(s, hdr.subj);
} /* if */
} /* if */
} /* if */
if (s != NULL) {
gotoxy(9,1);
bprintf("Looking at %s #%d for \"%s\"",
arealist[area].description,tmp,prompt);
video_update();
clreol(); /* vvv is ignored and 's' is changed */
tmp2 = bmgSearch(s,strlen(s),&pattern);
ptrfree(s); s = NULL;
if (tmp2 && (lastfound != tmp)) { /* found new one */
lastfound = tmp;
set_color(co_normal);
return;
} /* if */
} /* if */
if (keypressed()) {
if (getkey() == ABORT) {
set_color(co_normal);
return;
} /* if */
} /* if */
tmp = msgnext(CurBoard, tmp2 = tmp);
if (tmp != 0)
setcur(CurBoard,tmp);
} while ((tmp != 0) && (tmp != tmp2));
if (!globsrch) break; /* not global search, exit */
if (++area >= areas)
area = 0;
if (area == curarea) break; /* searched through all */
tmp = firstmsg(CurBoard); /* skip to first message of next board */
setcur(CurBoard,tmp);
} /* forever */
beep(0,0);
set_color(co_normal);
} /* srch */
BOOLEAN confirm(int confirmations)
{
int ch;
if (!confirmations)
return(TRUE);
gotoxy(9,1);
clreol();
set_color(co_warn);
bputs("*warning* ");
bputs("Do you really want to do this? (y/n) ");
video_update();
do {
ch = getkey() & 0x7f;
ch = tolower(ch); /* tolower might be a macro */
} while ((ch != 'y') && (ch != 'n'));
bputc((char) ch);
set_color(co_normal);
return(ch == 'y');
} /* confirm */
/*
* Set highest message read and set 'root' to current message
* There may be problems here, with msgnum and filemsg ...
* ... think about it sometime
*/
void highest()
{
if (msgat(CurBoard,curmsg(CurBoard)))
root = curmsg(CurBoard); /* global */
if (root > lastreadmsg(CurBoard))
setlastread(CurBoard, root);
} /* highest */
void left()
{
int temp;
back = curmsg(CurBoard);
direction = LEFT;
if (back <= firstmsg(CurBoard))
beep(0,0); /* must check here, msgprev doesn't give error */
if ((temp = msgprev(CurBoard, back)) == 0)
temp = firstmsg(CurBoard);
setcur(CurBoard, temp);
highest(); /* set root */
} /* left */
void right()
{
int temp;
back = curmsg(CurBoard);
direction = RIGHT;
if (back >= lastmsg(CurBoard))
beep(0,0); /* must check here, msgnext doesn't give error */
if ((temp = msgnext(CurBoard, back)) == 0)
temp = lastmsg(CurBoard);
setcur(CurBoard, temp);
highest();
} /* right */
void movetop()
{
back = curmsg(CurBoard);
direction = LEFT;
setcur(CurBoard,lastmsg(CurBoard));
highest();
} /* movetop */
void movebot()
{
back = curmsg(CurBoard);
direction = RIGHT;
setcur(CurBoard,firstmsg(CurBoard));
highest(); /* set root */
} /* movebot */
void enter()
{
if (direction == RIGHT)
right();
else
left();
} /* enter */
void nextto()
{
int new;
int look = area;
int startarea = area;
set_color(co_info);
do {
gotoxy(9,1);
bprintf("Looking for new mail to you in '%s'",arealist[look].description);
video_update();
clreol();
new = searchto(arealist[look].board, curmsg(arealist[look].board), username);
if (keypressed()) {
if (getkey() == ABORT) {
set_color(co_normal);
return;
} /* if */
} /* if */
} while ((globsrch) && (new == -1) &&
((++look >= areas ? look = 0 : look) != startarea));
set_color(co_normal);
if (new == -1) {
beep(0,0);
return;
} /* while */
area = look;
setcur(CurBoard,new);
/* highest(); */ /* not here */
} /* nextto */
static void gotomsg(int i)
{
int f,l;
f = /* firstmsg(CurBoard) */ 0; /* 8/2/90 */
l = lastmsg(CurBoard);
gotoxy(9, 1);
clreol();
set_color(co_info);
bprintf("Goto Message #? (%d-%d) ", f, l);
set_color(co_normal);
back = curmsg(CurBoard);
i = getnum(f, l, i);
if (i == 0) /* ignore it */
return;
if (!msgat(CurBoard,i))
i = msgnext(CurBoard,i);
setcur(CurBoard, i);
if (!msgat(CurBoard,i))
setcur(CurBoard, back);
else
highest();
} /* gotomsg */
void newarea()
{
int newarea;
if (!flushmsgbase())
fatal("Error writing message base");
if (areas < 2)
return;
newarea = selectarea(NULL);
if (newarea != -1)
toarea(newarea); /* show menu */
} /* newarea */
void nextarea()
{
int look = area;
/* look for next board with mail */
while ((++look >= areas ? look = 0 : look) != area)
if (lastmsg(arealist[look].board) > lastreadmsg(arealist[look].board))
break;
if (look != area) {
toarea(look);
} else {
toarea(0); /* go to first area */
beep(0,0);
}
} /* nextarea */
void prevarea()
{
int look = area;
/* look for prev board with mail */
while ((--look < 0 ? look = areas-1 : look) != area)
if (lastmsg(arealist[look].board) > lastreadmsg(arealist[look].board))
break;
if (look != area)
toarea(look);
else
beep(0,0);
} /* prevarea */
void uparea()
{
toarea(area+1 >= areas ? 0 : area+1);
} /* uparea */
void downarea()
{
toarea(area <= 0 ? areas-1 : area-1);
} /* downarea */
static void toarea(int n)
{
area = n;
override = FALSE;
direction = RIGHT;
back = root = curmsg(CurBoard);
clearbuffer(&msgbuf);
} /* toarea */
static void checkbase(void)
{
BYTE board;
int result;
gotoxy(1, maxy-3);
bputs("Checking message base... ");
video_update();
result = checkmsgbase(&board);
if (result == CHK_NOERR) {
bputs("No errors found.");
} else {
char *msg = NULL;
switch (result) {
case CHK_NONINC:
msg = "Non-increasing numbers found in board %d";
break;
case CHK_COUNTS:
msg = "MSGINFO.BBS and MSGIDX.BBS differ in board %d";
break;
case CHK_HDR:
msg = "Length of MSGHDR.BBS differs from MSGIDX.BBS";
break;
case CHK_TO:
msg = "Length of MSGTOIDX.BBS differs from MSGIDX.BBS";
break;
} /* switch */
gotoxy(1, maxy-3);
set_color(co_warn);
bputs("Error: ");
bprintf(msg, board);
clreol();
gotoxy(1, maxy-2);
bputs("You should exit and run MSGPACK -I to rebuild your index files.");
set_color(co_normal);
} /* else */
} /* checkbase */
static void usage_exit(void)
{
printf("\nUsage: MsgedQ [switches] [configfile [areasfile]]\n\n");
printf(" -q Read QuickBBS config files\n");
printf(" -r Read RemoteAccess config files\n");
#ifdef DBRIDGE
printf(" -b Read D'Bridge config files\n");
#endif
printf(" -d Config trace mode for debugging\n");
printf(" -nPath Write new config file and define Path as netmail directory\n");
printf(" -uName Override username from config file (use \"_\" for space)\n");
printf(" -p Protect netmail\n");
exit(255);
} /* usage_exit */
static int start(int argc, char *argv[])
{
char *uname = NULL;
char *cfg = NULL, *afn = NULL;
printf("Msged/Q " VERSION " Copyright 1991 Pieter J. Muller\n");
configdebug = quicksysop = rastruct = protectnet = FALSE;
#ifdef DBRIDGE
dbridgestruct = FALSE;
#endif
useusersbbs = TRUE; /* could be configurable */
while (--argc) {
if (**(++argv) == '-') {
switch (tolower(argv[0][1])) {
case 'n':
newnetpath = &argv[0][2];
createconfig = (*newnetpath != EOS);
if (createconfig) configdebug = TRUE;
if (createconfig && (newnetpath[strlen(newnetpath)-1] != '\\')) {
newnetpath = malloc(strlen(newnetpath)+2);
strcpy(newnetpath,&argv[0][2]);
strcat(newnetpath,"\\");
} /* if */
break;
case 'u': { char *c;
uname = &argv[0][2];
for (c = uname; *c != EOS; ++c)
if (*c == '_') *c = ' ';
break;
}
case 'p':
protectnet = TRUE;
break;
case 'd':
configdebug = TRUE;
break;
case 'q':
quicksysop = TRUE;
break;
case 'r':
rastruct = TRUE;
break;
#ifdef DBRIDGE
case 'b':
dbridgestruct = TRUE;
break;
#endif
case 'h':
case '?':
usage_exit();
default:
printf("Unknown switch '-%c'\n", argv[0][1]);
break;
} /* switch */
} else {
if (cfg == NULL)
cfg = *argv;
else
if (afn == NULL)
afn = *argv;
} /* else */
} /* while */
/* (void)putenv("PROMPT=Msged/Q $P$G"); */
printf("Initialising...\n");
memset(&message, 0, sizeof(message));
opening(cfg,afn,uname);
message.to = thisnode[CurAKA];
if (message.to.domain != NULL)
message.to.domain = strdup(message.to.domain);
if (!openmsgbase())
fatal("Cannot open message base.");
checkbase();
gotoxy(1, maxy);
bputs("Scanning for new mail....");
video_update();
area = areas-1; /* search forward from last area */
nextarea(); /* next area with new mail */
gotoxy(1, maxy);
bputs("Press any key to continue....");
clreol();
video_update();
getkey();
return(KAREA);
} /* start */
#ifdef ZAPTHISOUT
/*
* Execute a Dos command
* If path==NULL, execute COMSPEC
* command may be NULL
* Return TRUE iff ok
*/
BOOLEAN shell(char *path, char *command)
{
if (path == NULL)
if ((path = getenv("COMSPEC")) == NULL)
return FALSE;
if (spawnlp(P_WAIT, path, path, command, NULL) == -1)
return FALSE;
return TRUE;
} /* shell */
#endif
#ifndef MINI
static void far shell_msg(char swapmode, long amount)
{
if (swapmode != SWAP_NONE) {
bprintf("Swapping %ld bytes to %s\n", amount,
swapmode==SWAP_EMS ? "EMS" : "disk");
gotoxy(1, wherey()+1);
video_update();
}
} /* shell_msg */
void os()
{
void *temp = shell_message;
shell_message = shell_msg;
cls();
if (!flushmsgbase())
fatal("Error writing message base");
bputs("Type EXIT to return to Msged/Q.");
gotoxy(1,3); video_update();
if (!shell(NULL,NULL)) {
gotoxy(9,1);
set_color(co_warn);
bputs("Could not shell, press any key");
clreol();
set_color(co_normal);
video_update();
(void)getkey();
} /* if */
shell_message = temp;
video_init();
} /* os */
#endif
void beep(int freq, int len)
{
#if defined(__TURBOC__) || defined(__JPIC__)
static char state = 0;
#define timer() (*(long far *)MK_FP(0, 0x046c))
#define waitedge() { long v = timer(); while (v == timer()) /* */; }
if (!beepson) return;
if (state == 0) {
long value = timer();
sleep(1);
if (value == timer())
state = 1; /* disable all further beep calls */
else
state = 2; /* enable normal working */
} /* if */
if (state == 1) return; /* beeps disabled */
if (freq == 0) freq = ENDFREQ;
if (len == 0) len = ENDLEN;
waitedge();
sound(freq);
while (len--)
waitedge();
nosound();
#endif
} /* beep */
#ifndef SETTINGS
void settings() {}
#endif